package com.ruoyi.common.utils.http;

import com.ruoyi.project.ins.domain.InsWebProxy;
import com.ruoyi.project.ins.utils.HttpResult;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
public class OkHttpUtils {
    private final static int timeout = 30; // 单位秒

    // 全局 OkHttpClient（可复用）
    private static final OkHttpClient baseClient = new OkHttpClient.Builder()
        .connectTimeout(timeout, TimeUnit.SECONDS)
        .writeTimeout(timeout, TimeUnit.SECONDS)
        .readTimeout(timeout, TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .build();

    /** 根据 InsWebProxy 构建 OkHttpClient */
    public static OkHttpClient buildClientWithWebProxy(InsWebProxy proxy) {
        if (proxy == null) {
            return baseClient;
        }
        // 生成随机 sessid
        Random random = new Random();
        String part1 = String.format("%010d", random.nextInt(1_000_000_000));
        String part2 = String.format("%05d", random.nextInt(100_000));
        String sessionId = part1 + "_" + part2;

        // 动态使用国家码，默认 US
        String countryCode = proxy.getCountryCode() != null ? proxy.getCountryCode() : "US";

        // 构造代理用户名
        String proxyUser = String.format("customer-%s-cc-%s-sessid-%s", proxy.getProxyCustomer(), countryCode, sessionId);
        String proxyPassword = proxy.getProxyPassword();

        Proxy okProxy = new Proxy(Proxy.Type.HTTP,
            new InetSocketAddress(proxy.getProxyServer(), Integer.parseInt(proxy.getProxyPort())));

        return baseClient.newBuilder()
            .proxy(okProxy)
            .proxyAuthenticator((route, response) -> {
                String credential = Credentials.basic(proxyUser, proxyPassword);
                return response.request().newBuilder()
                    .header("Proxy-Authorization", credential)
                    .build();
            }).build();
    }

    /** GET 请求（支持代理和自定义Header） */
    public static HttpResult sendGetWithProxy(String url, Map<String, String> headers, InsWebProxy proxy) {
        OkHttpClient client = buildClientWithWebProxy(proxy);

        okhttp3.Request.Builder builder = new okhttp3.Request.Builder().url(url);
        if (headers != null) {
            headers.forEach((key, value) -> {
                if (key != null && value != null) {
                    builder.addHeader(key, value);
                }
            });
        }

        try (okhttp3.Response response = client.newCall(builder.build()).execute()) {
            int statusCode = response.code();
            String body = response.body() != null ? response.body().string() : "";
            // ✅ 收集所有响应头
            Map<String, String> headerMap = new HashMap<>();
            for (String name : response.headers().names()) {
                headerMap.put(name, response.header(name));
            }
            log.info("GET {} 响应码={}", url, statusCode);
            return new HttpResult(statusCode, body, headerMap);
        } catch (Exception e) {
            log.error("GET请求异常 - {}", url, e);
            return new HttpResult(-1, e.getMessage());
        }
    }

    /** POST 请求（支持代理和自定义Header） */
    public static HttpResult sendPostWithProxy(String url, Map<String, String> headers, Map<String, String> params,
        InsWebProxy proxy) {
        OkHttpClient client = buildClientWithWebProxy(proxy);
        okhttp3.FormBody.Builder formBuilder = new okhttp3.FormBody.Builder();
        if (params != null) {
            params.forEach(formBuilder::add);
        }
        okhttp3.RequestBody body = formBuilder.build();
        okhttp3.Request.Builder builder = new okhttp3.Request.Builder().url(url).post(body);
        if (headers != null) {
            headers.forEach((key, value) -> {
                if (key != null && value != null) {
                    builder.addHeader(key, value);
                }
            });
        }
        try (okhttp3.Response response = client.newCall(builder.build()).execute()) {
            int statusCode = response.code();
            String responseBody = response.body() != null ? response.body().string() : "";
            log.info("POST {} 响应码={}", url, statusCode);
            return new HttpResult(statusCode, responseBody);
        } catch (Exception e) {
            log.error("POST请求异常 - {}", url, e);
            return new HttpResult(-1, e.getMessage());
        }
    }
}
